package com.gitee.apanlh.util.net.ftp;

import com.gitee.apanlh.exp.FtpConfigException;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.encode.CharsetCode;
import com.gitee.apanlh.util.unit.BuffSize;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;

import java.time.Duration;

/**	
 * 	FTP配置自动装配
 * 
 * 	@author Pan
 */
class FtpStarterConfigure implements FtpConfigureHandler {
	
	/** 默认全局超时45秒 */
	static final int DEFAULT_TIMEOUT = 45000;
	
	/** FTP客户端 */
	private FTPClient client;
	/** FTP配置 */
	private FtpConfig config;
	
	/**
	 * 	默认构造函数
	 * 	@author Pan
	 */
	FtpStarterConfigure() {
		
	}
	
	/**	
	 * 	构造函数-配置自动装配
	 * 	
	 * 	@author Pan
	 * 	@param 	client	FTPClient
	 * 	@param 	config	FtpConfig
	 */
	public FtpStarterConfigure(FTPClient client, FtpConfig config) {
		this.client = client;
		this.config = config;
	}
	
	/**
	 * 	设置FTP连接模式
	 * 	
	 * 	@author Pan
	 */
	void setConnectMode() {
		if (config.getConnectMode() == null) {
			config.setConnectMode(FtpConnectMode.ACTIVE);
		}

		if (Eq.enums(FtpConnectMode.ACTIVE, config.getConnectMode())) {
			client.enterLocalActiveMode();
		}
		if (Eq.enums(FtpConnectMode.PASSIVE, config.getConnectMode())) {
			client.enterLocalPassiveMode();
		}
	}
	
	/**	
	 * 	设置编码默认装配UTF-8
	 * 	
	 * 	@author Pan
	 */
	void setEncoding() {
		String encoding = config.getEncoding();
		if (encoding == null) {
			config.setEncoding(CharsetCode.UTF_8);
			client.setControlEncoding(CharsetCode.UTF_8);
			return ;
		}
		client.setControlEncoding(encoding);
	}
	
	/**	
	 * 	设置建立连接超时时间
	 * 	
	 * 	@author Pan
	 */
	void setConnectTimeout() {
		if (existGlobalTimeout()) {
			client.setConnectTimeout(config.getGlobalTimeOut());
			return ;
		}
		
		int timeout = config.getConnectTimeout();
		if (timeout <= 0) {
			timeout = DEFAULT_TIMEOUT;
			config.setConnectTimeout(timeout);
		}
		client.setConnectTimeout(timeout);
	}
	
	/**	
	 * 	设置控制命令超时时间
	 * 
	 * 	@author Pan
	 */
	void setCommandTimeout() {
		if (existGlobalTimeout()) {
			client.setDefaultTimeout(config.getGlobalTimeOut());
			return ;
		}
		
		int timeout = config.getConnectTimeout();
		if (timeout <= 0) {
			timeout = DEFAULT_TIMEOUT;
			config.setCommandTimeout(timeout);
		}
		client.setDefaultTimeout(timeout);
	}
	
	/**	
	 * 	用于设置针对传输文件超时时间
	 * 	
	 * 	@author Pan
	 */
	void setDataTransferTimeout() {
		if (existGlobalTimeout()) {
			client.setDataTimeout(Duration.ofMillis(config.getGlobalTimeOut()));
			return ;
		}

		int timeout = config.getDataTimeout();
		if (timeout <= 0) {
			timeout = DEFAULT_TIMEOUT;
			config.setDataTimeout(timeout);
		}
		client.setDataTimeout(Duration.ofMillis(timeout));
	}
	
	/**	
	 * 	存在全局超时设置
	 * 	
	 * 	@author Pan
	 * 	@return	boolean
	 */
	private boolean existGlobalTimeout() {
		return config.getGlobalTimeOut() > 0L;
	}
	
	/**
	 * 	设置各个超时时长（毫秒）
	 * 	@author Pan
	 */
	void setTimeout() {
		setConnectTimeout();
		setCommandTimeout();
		setDataTransferTimeout();
	}
	
	/**	
	 * 	设置FTP缓冲
	 * 	
	 * 	@author Pan
	 */
	void setBufferSize() {
		try {
			int receiveBufferSize = config.getReceiveBufferSize();
			int sendBufferSize = config.getSendBufferSize(); 
			
			//	默认8K
			if (receiveBufferSize <= 0) {
				receiveBufferSize = BuffSize.SIZE_8K;
				config.setReceiveBufferSize(receiveBufferSize);
			}
			if (sendBufferSize <= 0) {
				sendBufferSize = BuffSize.SIZE_8K;
				config.setSendBufferSize(sendBufferSize);
			}
			
			client.setReceiveBufferSize(receiveBufferSize);
			client.setBufferSize(sendBufferSize);
		} catch (Exception e) {
			throw new FtpConfigException(e.getMessage(), e);
		}
	} 
	
	/**
	 * 	设置传输文件类型
	 * 	@author Pan
	 */
	void setFileTypeAndTransferMode() {
		try {
			int fileType = config.getFileTransferMode();
			int fileTransferMode = config.getFileTransferMode();
			
			// 设置默认传输文件类型(二进制、字节流形式传输)
			if (fileType <= 0) {
				fileType = FTP.BINARY_FILE_TYPE;
			}
			if (fileTransferMode <= 0) {
				fileTransferMode = FTP.STREAM_TRANSFER_MODE;
			}
			
			client.setFileType(fileType);
			client.setFileTransferMode(fileTransferMode);
		} catch (Exception e) {
			throw new FtpConfigException(e.getMessage(), e);
		} 
	}

	@Override
	public void beforeConfigure() {
		setEncoding();
		setTimeout();
	}

	@Override
	public void afterConfigure() {
		setConnectMode();
		setBufferSize();
		setFileTypeAndTransferMode();
	}
}
